/*
 * Font.java
 *
 * Created on October 11, 2009, 1:03 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package com.nextel.util.lwuit;

import com.nextel.ui.OUILook;

/**
 * A simple abstraction of platform fonts and library fonts that enables the
 * library to use more elaborate fonts unsupported by a specific device.
 * This abstraction also supports bitmap fonts using an Ant task (more details
 * about the unifier are explained in the javadoc overview document).
 * <p>A bitmap font can be created manually but that is tedious, normally you would use
 * the Ant task as illustrated bellow to produce a resource file containing
 * the supported bitmap font. For further detail read the overview document and 
 * {@link com.sun.lwuit.util.Resources}.
<pre>
&lt;target name="pre-init"&gt;
&lt;taskdef classpath="ImageUnifier.jar" classname="com.sun.jwt.resource.Builder" name="build" /&gt;
&lt;build dest="src/font.res"&gt;
&lt;font src="images/arial.ttf" bold="true" italic="true" size="11" /&gt;
&lt;font logicalName="Dialog" /&gt;
&lt;/build&gt;
&lt;/target&gt;
</pre>
 * <p>The following attributes can be expressed for a font ant task:
 * <ul>
 * <li>name - name for the font to load from the resource file (optional: defaults to logical name or file name).
 * <li>charset - defaults to the English alphabet, numbers and common signs. 
 * Should contain a list of all characters that should be supported by a font. E.g. if a font would always be
 * used for uppercase letters then it would save space to define the charset as: {@code "ABCDEFGHIJKLMNOPQRSTUVWXYZ" }
 * <li>src - font file in the case of using a file, defaults to TrueType font
 * <li>size - floating point size of the font
 * <li>bold - defaults to false indicates if the font should be bold
 * <li>italic - defaults to false indicates if the font should be italic
 * <li>trueType - defaults to true, relevant only when src is used. If set to false type 1 fonts are assumed.
 * <li>antiAliasing - defaults to true otherwise fonts will be aliased
 * <li>logicalName - logical name of the font as specified by java.awt.Font in Java SE: 
 * {@code Dialog, DialogInput, Monospaced, Serif, or SansSerif }
 * </ul>
 */
public abstract class Font {

    /**
     * Creates a new Font
     */
    Font() {
    }

    /**
     * Creates a bitmap font with the given arguments and places said font in the cache
     * 
     * @param name the name for the font in the cache
     * @param bitmap a transparency map in red and black that indicates the characters
     * @param cutOffsets character offsets matching the bitmap pixels and characters in the font 
     * @param charWidth The width of the character when drawing... this should not be confused with
     *      the number of cutOffset[o + 1] - cutOffset[o]. They are completely different
     *      since a character can be "wider" and "seep" into the next region. This is
     *      especially true with italic characters all of which "lean" outside of their 
     *      bounds.
     * @param charsets the set of characters in the font
     * @return a font object to draw bitmap fonts
     */
    public static void createBitmapFont(String name, Image bitmap, int[] cutOffsets, int[] charWidth, String charsets) {

        int colorFont = OUILook.PLAIN_SMALL_TEXT_COLOR;
        Font f = null;
        if (name.equals(OUILook.NOMBRE_TEXTO)) {

            colorFont = OUILook.PLAIN_SMALL_SOFTKEY_COLOR;//BLANCO
            f = createBitmapFont(bitmap, cutOffsets, charWidth, charsets, name, colorFont);
            OUILook.PLAIN_SMALL_SOFTKEY = f;//bitmapCache.put(OUILook.NOMBRE_SOFTKEY, f);

            colorFont = OUILook.PLAIN_SMALL_TITULO_COLOR; //ROJO
            f = createBitmapFont(bitmap, cutOffsets, charWidth, charsets, name, colorFont);
            OUILook.PLAIN_SMALL_TITLE = f;//bitmapCache.put(OUILook.NOMBRE_TITULO, f);

//        } else if (name.equals(OUILook.NOMBRE_TEXTO)) {

            colorFont = OUILook.PLAIN_SMALL_TEXT_COLOR; //NEGRO
            f = createBitmapFont(bitmap, cutOffsets, charWidth, charsets, name, colorFont);
            OUILook.PLAIN_SMALL_TEXT = f; //bitmapCache.put(OUILook.NOMBRE_TEXTO, f);

//            colorFont = OUILook.PLAIN_SMALL_MESSAGE_COLOR;
//            f = createBitmapFont(bitmap, cutOffsets, charWidth, charsets, name, colorFont);
//            OUILook.PLAIN_SMALL_MESSAGE = f; //bitmapCache.put(OUILook.NOMBRE_MENSAJE, f);

        }
        
        
        f = null;
//        return f;
    }

    /**
     * Creates a bitmap font with the given arguments
     * 
     * @param bitmap a transparency map in red and black that indicates the characters
     * @param cutOffsets character offsets matching the bitmap pixels and characters in the font 
     * @param charWidth The width of the character when drawing... this should not be confused with
     *      the number of cutOffset[o + 1] - cutOffset[o]. They are completely different
     *      since a character can be "wider" and "seep" into the next region. This is
     *      especially true with italic characters all of which "lean" outside of their 
     *      bounds.
     * @param charsets the set of characters in the font
     * @return a font object to draw bitmap fonts
     */
    public static Font createBitmapFont(Image bitmap, int[] cutOffsets, int[] charWidth, String charsets, String idFont, int color) {
        return new CustomFont(bitmap, cutOffsets, charWidth, charsets, idFont, color);
    }

    /**
     * Return the width of the given characters in this font instance
     * 
     * @param ch array of characters
     * @param offset characters offsets
     * @param length characters length
     * @return the width of the given characters in this font instance
     */
    public int charsWidth(char[] ch, int offset, int length) {
        int retVal = 0;
        for (int i = 0; i < length; i++) {
            retVal += charWidth(ch[i + offset]);
        }
        return retVal;
    }

    /**
     * Return the width of the given string subset in this font instance
     * 
     * @param str the given string
     * @param offset the string offset
     * @param len the len od string
     * @return the width of the given string subset in this font instance
     */
    public int substringWidth(String str, int offset, int len) {
        return charsWidth(str.toCharArray(), offset, len);
    }

    /**
     * Return the width of the given string in this font instance
     * 
     * @param str the given string     * 
     * @return the width of the given string in this font instance
     */
    public int stringWidth(String str) {
        if (str == null || str.length() == 0) {
            return 0;
        }
        return substringWidth(str, 0, str.length());
    }

    /**
     * Return the width of the specific character when rendered alone
     * 
     * @param ch the specific character
     * @return the width of the specific character when rendered alone
     */
    public abstract int charWidth(char ch);

    /**
     * Return the total height of the font
     * 
     * @return the total height of the font
     */
    public abstract int getHeight();

    /**
     * Draw the given char using the current font and color in the x,y 
     * coordinates.
     * 
     * @param g the graphics object
     * @param character the given character
     * @param x the x coordinate to draw the char
     * @param y the y coordinate to draw the char
     */
    abstract void drawChar(Graphics g, char character, int x, int y);



    /**
     * Draw the given char array using the current font and color in the x,y 
     * coordinates
     * 
     * @param g the graphics object
     * @param data the given char array 
     * @param offset the offset in the given char array
     * @param length the number of chars to draw
     * @param x the x coordinate to draw the char
     * @param y the y coordinate to draw the char
     */
    void drawChars(Graphics g, char[] data, int offset, int length, int x, int y) {
//        System.out.println("empieza el dibujado 5");
//        System.out.println("Font.drawChars() dibujando los chars");
        char c;
        for (int i = 0; i < length; i++) {
            c = data[offset + i];
            drawChar(g, c, x, y);
            x += charWidth(c);
        }
    }

}
